feat(minidump): Add sentry-minidump integration - #1315
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
szokeasaurusrex
left a comment
There was a problem hiding this comment.
For the most part, this looks good, but I left a couple suggestions I think we should implement before merging.
I tested it out locally and the crashes are showing up nicely in the UI.
There was a problem hiding this comment.
h: We generate these README.md files with cargo readme in the version-bumping script, using this command:
The files are generated from the crate-level documentation in src/lib.rs. It seems that this README contains some information not included in src/lib.rs, so you should move that information into src/lib.rs so that the README survives regeneration.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #1315 +/- ##
==========================================
+ Coverage 73.81% 74.14% +0.32%
==========================================
Files 64 79 +15
Lines 7538 9950 +2412
==========================================
+ Hits 5564 7377 +1813
- Misses 1974 2573 +599 |
…h/sentry-rust into feat/minidump-integration
|
@szokeasaurusrex do you think we should set the default process name as |
Yes, I think that's a good idea, but I'd also include some indication that the process is part of the Rust SDK. I think something like "Sentry Rust SDK Crash Reporter" or "Crash Reporter (Sentry Rust SDK)" could work well. |
szokeasaurusrex
left a comment
There was a problem hiding this comment.
Looks like you addressed my previous feedback 🙏
I identified a couple more small items but lgtm in general; please ping me when this is ready to be merged
|
@timfish if I understand correctly, after this change is released, the existing The one thing I am not sure about is whether Craft will be able to create a new crate when releasing, or if it will error because the crate does not exist yet. I haven't released a new crate at Sentry before so this may be worth looking into |
At some point I will publish a release of
|
Make some improvements to the `sentry-minidump` e2e test that will make the test more reliable and faster: - Allow the OS to assign an available port for the test rather than hardcoding port `8123` (or another fixed port), which causes the test to fail when that port is occupied - Add a timeout for the child process to ensure the test does not get stuck waiting forever if the child process does not exit - Lower existing timeouts and delays to make the test run faster
| return; | ||
| } | ||
| match self.build_child().spawn() { | ||
| Ok(handle) => { | ||
| let _ = self.handle.set(handle); | ||
| } | ||
| Err(err) => { | ||
| sentry_debug!("could not start crash reporter: {err}"); | ||
| } | ||
| } | ||
| }); |
There was a problem hiding this comment.
Bug: A panic within the setup function's call_once block can poison a static Once guard, causing subsequent sentry::init calls to panic immediately.
Severity: LOW
Suggested Fix
To prevent the Once from being poisoned, wrap the code inside the call_once closure with std::panic::catch_unwind. This will catch any panics, allowing the program to handle the error gracefully without poisoning the static Once guard and preventing subsequent initializations from crashing.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: sentry-minidump/src/lib.rs#L456-L477
Potential issue: The `setup` function uses a static `std::sync::Once` to ensure its
initialization logic runs only once. If a panic occurs within the closure passed to
`SETUP.call_once`, for instance, if an integration's `setup()` method panics during the
creation of the crash reporter client, the `Once` object becomes poisoned. Any
subsequent attempt to initialize the client by calling `sentry::init` will trigger
`setup` again. The subsequent call to `SETUP.call_once` will then immediately panic
because the `Once` is poisoned, leading to a crash. While this requires a second
`sentry::init` call after a panic, it represents a potential unhandled crash condition.
There was a problem hiding this comment.
I think this is ok, because we would have already panicked, and multiple initializations are rare
Adds a new
sentry-minidumpcrate that captures native crashes as minidumps in a separate process and sends them to Sentry as attachments. Enable it with theminidumpfeature onsentry. Linux, macOS and Windows only.The code is ported from the standalone
sentry-rust-minidumpcrate.How it works
The integration re-executes the current binary as a crash reporter process. The app process spawns the reporter and connects to it; the reporter attaches a native crash handler and waits. On a crash it writes a minidump, attaches it to a
Fatalevent, and uploads it. Scope does not cross the process boundary on its own. To give the crash event context (user, tags, extra, breadcrumbs), the app sends updates to the reporter explicitly through methods on the integration; each call is forwarded over a socket and applied to the reporter's scope.Difference from
sentry-rust-minidumpIn
sentry-rust-minidumpthe process model is explicit: you callinit(&client), which re-executes the binary, and you then have to pass the client in by hand, keep the returnedHandlealive for the life of the program (orleak()it), and know that everything beforeinitruns in both processes.Here the process work moves inside
Integration::setup, which runs insideClient::with_optionsbeforesentry::initbinds the client to the hub. That removes most of the ceremony:setupspawns the reporter and keeps the handle inside the integration, which the client owns for the life of the process. NoHandle, noleak(), no client to pass in.setupnever returns. It builds its own client from the clonedClientOptions, runs the minidump server loop, and exits.sentry::initis the last line ofmainthat runs there.Scope sync is still manual, reached via
sentry::with_integrationinstead of a method on aHandle.inherit_argsnow defaults totruesince I suspect this will be more useful to most without causing pain for others.The one caveat is inherent to re-executing the binary: code before
sentry::initstill runs in both processes.is_crash_reporter_process()stays public so apps can gate on that.Resolves #1316